<template>
  <template v-if="!props.selectedRowKey">
    <a-table
      class="ant-table-striped enter-y"
      size="middle"
      :columns="(props.columns as any)"
      :data-source="searchResultData"
      :row-class-name="((_record: any, index: any) => (index % 2 === 1 ? 'table-striped' : null ) as any)"
      bordered
      :loading="props.loading"
      :pagination="(paginations as any)"
      @change="handleTableChange"
    >
      <template #title>
        <div class="flex justify-between w-full items-center">
          <span class="w-60">
            <slot name="title"></slot>
          </span>
          <section class="flex gap-4 items-center">
            <slot name="function"></slot>
            <div>
              <a-input-group compact>
                <a-select v-model:value="selectValue">
                  <a-select-option v-for="i in searchSelectOption" :value="i.value">
                    {{ i.label }}
                  </a-select-option>
                </a-select>
                <a-input
                  v-model:value="searchValue"
                  style="width: 200px"
                  @change="debouncedFn"
                  placeholder="输入相关信息进行搜索"
                  :allowClear="true"
                />
              </a-input-group>
            </div>
          </section>
        </div>
      </template>
      <template #bodyCell="{ record, column }" v-if="props.personalized">
        <template v-if="column.dataIndex === 'status'">
          <a-switch
            :checked="record.status === 0 ? false : true"
            checked-children="启用"
            un-checked-children="禁用"
          />
        </template>
        <template v-else-if="column.dataIndex === 'roleId'">
          <span>
            {{ getRoleName(record.roleId) }}
          </span>
        </template>
        <template v-else-if="column.dataIndex === 'operation'">
          <div class="flex justify-center gap-4">
            <div
              class="cursor-pointer text-lg text-blue-500"
              @click="openModifyUserDataForm(record.key)"
            >
              <form-outlined />
            </div>

            <div class="cursor-pointer text-lg text-red-500" @click="deleteSelect(record.key)">
              <delete-outlined />
            </div>
          </div>
        </template>
        <template v-else-if="column.dataIndex === 'loginTime'">
          {{ record.loginTime }}
        </template>
        <template v-else-if="column.dataIndex === 'addTime'">
          {{ record.addTime }}
        </template>
        <template v-else-if="column.dataIndex === 'exam_deadline'">
          {{ record.exam_deadline }}
        </template>
        <template v-else-if="column.dataIndex === 'sex'">
          {{ record.sex === 0 ? '女' : '男' }}
        </template>
      </template>
    </a-table>
  </template>
  <template v-else>
    <a-table
      class="ant-table-striped enter-y"
      :row-selection="{ selectedRowKeys: props.selectedRowKey as number[] | string[], onChange: onSelectChange } "
      size="middle"
      :columns="(props.columns as any)"
      :data-source="searchResultData"
      :row-class-name="((_record: any, index: any) => (index % 2 === 1 ? 'table-striped' : null ) as any)"
      bordered
      :loading="props.loading"
      :pagination="(paginations as any)"
      @change="handleTableChange"
    >
      <template #title>
        <div class="flex justify-between w-full items-center">
          <span class="w-60">
            <slot name="title"></slot>
          </span>
          <section class="flex gap-4 items-center">
            <slot name="function"></slot>
            <div>
              <a-input-group compact>
                <a-select v-model:value="selectValue">
                  <a-select-option v-for="i in searchSelectOption" :value="i.value">
                    {{ i.label }}
                  </a-select-option>
                </a-select>
                <a-input
                  v-model:value="searchValue"
                  style="width: 200px"
                  @change="debouncedFn"
                  placeholder="输入相关信息进行搜索"
                  :allowClear="true"
                />
              </a-input-group>
            </div>
          </section>
        </div>
      </template>
      <template #bodyCell="{ record, column }" v-if="props.personalized">
        <template v-if="column.dataIndex === 'status'">
          <a-switch
            :checked="record.status === 0 ? false : true"
            checked-children="启用"
            un-checked-children="禁用"
          />
        </template>
        <template v-else-if="column.dataIndex === 'roleId'">
          <span>
            {{ getRoleName(record.roleId) }}
          </span>
        </template>
        <template v-else-if="column.dataIndex === 'operation'">
          <div class="flex justify-center gap-4">
            <div
              class="cursor-pointer text-lg text-blue-500"
              @click="openModifyUserDataForm(record.key)"
            >
              <slot name="isModify">
                <form-outlined />
              </slot>
            </div>
            <div class="cursor-pointer text-lg text-red-500" @click="deleteSelect(record.key)">
              <delete-outlined />
            </div>
          </div>
        </template>
        <template v-else-if="column.dataIndex === 'login_time'">
          <span v-if="record.login_time">
            {{ record.login_time }}
          </span>
          <span v-else> 未登录 </span>
        </template>
        <template v-else-if="column.dataIndex === 'add_time'">
          {{ record.add_time }}
        </template>
        <template v-else-if="column.dataIndex === 'role'">
          {{ getRoleName(record.role) }}
        </template>
        <template v-else-if="column.dataIndex === 'exam_deadline'">
          {{ record.exam_deadline }}
        </template>
        <template v-else-if="column.dataIndex === 'sex'">
          {{ record.sex === 0 ? '女' : '男' }}
        </template>
      </template>
    </a-table>
  </template>
</template>

<script setup lang="ts">
  import { useDebounceFn } from '@vueuse/core';
  import { DeleteOutlined, FormOutlined } from '@ant-design/icons-vue';

  const props = defineProps({
    searchSelectOption: {
      type: Array,
    },
    columns: {
      type: Array,
    },
    loading: {
      type: Boolean,
    },
    allData: {
      type: Array,
    },
    total: {
      type: Number,
    },
    personalized: {
      default: () => false,
      type: Boolean,
    },
    selectedRowKey: {
      type: Array,
    },
  });
  const emits = defineEmits([
    'update:selectedRowKey',
    'modifyUserData',
    'handleSearchValue',
    'update:visible',
    'deleteSelectUser',
  ]);

  // 分页器配置
  let paginations = reactive({
    position: ['bottomRight'],
    total: props.total,
    pageSize: 10,
    hideOnSinglePage: false,
    current: 1,
    showSizeChanger: true,
    responsive: true,
    defaultPageSize: 10,
    showTotal: (total) => `共 ${total} 条数据`,
    pageSizeOptions: ['10', '20', '30', '40', '50'],
    size: 'middle',
  });

  const getRoleName = (
    role: { id: number; add_time: number; content: string; role_name: string }[]
  ) => {
    return role.map((item) => item.role_name).join(',');
  };
  // 列表数据
  const allData = computed((): any[] => props.allData as any[]);
  // 搜索框下拉列表
  const searchSelectOption = unref(props.searchSelectOption) as { value: string; label: string }[];
  // 搜索项
  let selectValue = ref(searchSelectOption[0].value);
  // 用于搜索
  let searchValue = ref('');
  // 搜索结果
  let searchResultData = ref<any[]>();
  watch(
    () => allData.value,
    (val) => {
      searchResultData.value = val;
    },
    {
      immediate: true,
      deep: true,
    }
  );
  // 处理输入框内容
  const handleChange = (e) => {
    const value = e?.target?.value.trim() || searchValue.value.trim();
    if (value === '') {
      searchResultData.value = allData.value;
      paginations.total = searchResultData.value.length;
      return;
    }
    searchResultData.value =
      allData.value.filter((item) => item[selectValue.value].includes(value)) ||
      allData.value.filter((item) => JSON.stringify(item.studentId).includes(value));
    paginations.total = searchResultData.value.length;
  };
  // 防抖
  const debouncedFn = useDebounceFn((e) => {
    handleChange(e);
  }, 500);
  // 选择框更改触发
  watch(
    () => selectValue.value,
    () => {
      //@ts-expect-error
      handleChange();
    }
  );
  // 勾选改变
  const onSelectChange = (selectedRowKeys: string[] | number[]) => {
    emits('update:selectedRowKey', selectedRowKeys);
  };
  // 修改用户姓名
  const openModifyUserDataForm = (key: string) => {
    emits('modifyUserData', key);
  };

  const handleTableChange = (pagination) => {
    paginations.current = pagination.current;
    paginations.pageSize = pagination.pageSize;
  };

  const deleteSelect = (key: string | number) => {
    emits('deleteSelectUser', [key]);
  };
</script>

<style scoped>
  .ant-table-striped :deep(.table-striped) td {
    @apply bg-[#fafafa] dark:(!bg-[#1d1d1d] text-light-900);
  }
  :deep(.ant-table) {
    @apply dark:(!bg-[#151515] text-light-900);
  }
  :deep(.ant-table-row) {
    @apply dark: (!bg-[#151515] text-light-900);
  }
  :deep(.ant-table table) {
    border-radius: 0;
  }
  :deep(.ant-table.ant-table-bordered > .ant-table-container) {
    @apply dark:border-[#303030];
  }
  :deep(.ant-table-title) {
    @apply dark:(bg-dark-900  border-[#303030] text-light-900) !pl-3 text-[16px];
  }

  :deep(.ant-table-thead > tr > th) {
    @apply dark:(!bg-[#1d1d1d] border-[#303030] text-light-900);
  }
  :deep(.ant-table.ant-table-bordered > .ant-table-container > .ant-table-content > table) {
    @apply dark:border-[#303030];
  }
  :deep(.ant-table.ant-table-bordered
      > .ant-table-container
      > .ant-table-content
      > table
      > thead
      > tr
      > th) {
    @apply dark:( border-[#303030]);
  }
  :deep(.ant-table-tbody > tr > th) {
    @apply text-white;
  }
  :deep(.ant-table.ant-table-bordered
      > .ant-table-container
      > .ant-table-content
      > table
      > tbody
      > tr
      > td) {
    @apply dark:border-[#303030];
  }

  :deep(.ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td) {
    @apply dark:!bg-[#262626];
  }
  :deep(.ant-table-body .ant-table-row-hover),
  :deep(.ant-table-body .ant-table-row-hover > td),
  :deep(.ant-table-body > tr.ant-table-row:hover > td),
  :deep(.ant-table-tbody > tr > td.ant-table-row-hover) {
    @apply dark:!bg-[#262626];
  }
  :deep(.ant-table-cell) {
    @apply dark:!bg-[#151515];
  }
  :deep(.ant-table-container) {
    @apply px-2 pb-2;
  }
  :deep(.ant-table-content) {
    @apply border-l border-solid border-[#f0f0f0] dark:border-[#303030];
  }
  :deep(.ant-select-arrow .anticon) {
    vertical-align: 6px !important;
  }
  :deep(.ant-select:not(.ant-select-customize-input) .ant-select-selector) {
    @apply dark:(bg-[#1d1d1d] text-light-50 border-[#303030]);
  }
  :deep(.ant-select-arrow) {
    @apply dark:text-light-50;
  }
  :deep(.ant-select:not(.ant-select-disabled):hover .ant-select-selector) {
    @apply dark:(border-blue-600);
  }
  :deep(.ant-input),
  :deep(.ant-input-affix-wrapper) {
    @apply dark:(bg-[#1d1d1d] text-light-50 border-[#303030]);
  }
  :deep(.ant-input-clear-icon) {
    @apply dark:text-light-50;
  }
  :deep(.ant-input:focus) {
    @apply dark:(border-[#303030]);
  }
  :deep(.ant-spin-container),
  :deep(.ant-table-wrapper) {
    @apply dark:bg-dark-800;
  }
  :deep(.ant-switch) {
    @apply dark:bg-gray-700;
  }
  :deep(.ant-switch-checked) {
    @apply dark:bg-blue-500;
  }
  :deep(.ant-pagination-total-text) {
    @apply dark:text-light-900;
  }
  :deep(.ant-pagination-item-ellipsis) {
    @apply dark:(text-light-900 bg-[#303030]);
  }
  :deep(.ant-pagination-item-link) {
    @apply dark:(text-light-900 bg-[#303030] border-[#303030]);
  }
  :deep(.ant-pagination-item) {
    @apply dark:(text-light-900 bg-[#303030] border-[#303030]);
  }
  :deep(.ant-pagination-item a) {
    @apply dark:(text-light-900);
  }
  :deep(.ant-pagination-item-active a) {
    @apply dark:text-blue-400;
  }
  :deep(.ant-pagination) {
    @apply dark:bg-black pt-4;
  }
  :deep(.ant-table-tbody > tr.ant-table-row-selected > td) {
    @apply bg-[#ffffff];
  }
  :deep(.ant-table-tbody > tr.ant-table-row-selected:hover > td) {
    @apply bg-[#dbdbdb];
  }
</style>
